using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

using Jeffrey.XFramework;
using Jeffrey.XFramework.XCrawl;

namespace Jeffrey.XProcess
{
    public class ExtractImages : Extractor
    {
        private static readonly String IMAGES_VALIDATE_PATTERN = @"^http://[^" + URI_EXCLUDE_CHARS + @"]+\.(" + ImagesFilter.IMAGES + @")$";
        private static readonly String IMAGES_EXTRACT_PATTERN  = @"\bhttp://[^" + URI_EXCLUDE_CHARS + @"]+\.(" + ImagesFilter.IMAGES + @")\b";
        private static readonly String IMAGES_EX_EXTRACTOR_PATTERN = @"<img +[^>]*src *=[ ""']*(?<image>[^" + URI_EXCLUDE_CHARS + "]+)[^>]*>";

        public ExtractImages(String name, String description, String classname, String path)
            : base(name, description, classname, path) { }
        public ExtractImages(String name, String description, String classname, String path, Filter filter)
            : base(name, description, classname, path, filter) { }

        protected override void  Extract(CrawlUri curi)
        {
            String ImageUri = null;
            //to validate images...
            Regex validate = new Regex(IMAGES_VALIDATE_PATTERN, RegexOptions.IgnoreCase);
            //to extract the http-link with images' extends...
            Regex reg = new Regex(IMAGES_EXTRACT_PATTERN, RegexOptions.IgnoreCase);
            //to extract the image in <img...src=..> pattern...
            Regex ex_reg = new Regex(IMAGES_EX_EXTRACTOR_PATTERN, RegexOptions.IgnoreCase);

            /*
             * try to find the images' link in the <img src...> pattern.
             */
            MatchCollection mcol = ex_reg.Matches(curi.Content);
            foreach (Match match in mcol)
            {
                try
                {
                    ImageUri = new CrawlUri(curi, match.Groups["image"].Value).AbsoluteUri;

                    if (validate.Match(ImageUri).Success)
                        curi.PriorLinks.Add(ImageUri);
                }
                catch (UriFormatException ufe)
                {
                    Logger.LogError(ufe, "occurred when create CrawUri using " + match.Value);
                }
            }

            /*
             * try to find the images' link not in <img src...> pattern.
             */
            mcol = reg.Matches(curi.Content);

            foreach (Match match in mcol)
            {
                try
                {
                    ImageUri = match.Value;

                    if (!curi.PriorLinks.Contains(ImageUri))
                        curi.PriorLinks.Add(ImageUri);
                }
                catch (UriFormatException ufe)
                {
                    Logger.LogError(ufe, "occurred when create CrawUri using " + match.Value);
                }
            }
        }
    }
}
